package com.dkm.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dkm.entity.Counselor;
import com.dkm.entity.Role;
import com.dkm.entity.Student;
import com.dkm.entity.Users;
import com.dkm.repository.CounselorRepository;
import com.dkm.repository.StudentRepository;
import com.dkm.repository.UsersRepository;
import com.dkm.service.CounselorService;
import com.dkm.util.ResultUtil;

@Service
public class CounselorServiceImpl implements CounselorService {

	//注入咨询师持久层
	@Autowired
	private CounselorRepository counselorRepository;
	//注入学生持久层
	@Autowired
	private StudentRepository studentRepository;
	//注入用户持久层
	@Autowired
	private UsersRepository usersRepository;
	
	@Override
	public Page<Counselor> findAllCounselors(Counselor counselor, Pageable pageable) {
		return counselorRepository.findAll(this.get(counselor), pageable);
	}

	private Specification<Counselor> get(Counselor counselor) {
		// TODO Auto-generated method stub
		return new Specification<Counselor>() {
			@Override
			public Predicate toPredicate(Root<Counselor> root, CriteriaQuery<?> query,
					CriteriaBuilder criteriaBuilder) {
				//1创建Predicate对象,动态sql表达式
				Predicate predicate =criteriaBuilder.conjunction();
				//2创建一个集合，存放多个条件,动态sql表达式集合
				List<Expression<Boolean>> expressions=predicate.getExpressions();
				
				return predicate;
			}
		};
	}
	
	@Override
	public Counselor getNetCounselorByUser_id(String user_id) {
		return counselorRepository.getNetCounselorByUser_id(user_id);
	}
	
	@Override
	public Counselor getCounselorByUser_id(String user_id) {
		return counselorRepository.getCounselorByUser_id(user_id);
	}

	@Override
	public ResultUtil updateCounselorWeight(Counselor counselor) {
		ResultUtil resultUtil=null;
		//根据id获取咨询师
		Counselor c=counselorRepository.findById(counselor.getCounselor_id()).get();
		//修改权重
		c.setWeight(counselor.getWeight());
		Counselor c1=counselorRepository.saveAndFlush(c);
		if(c1!=null) {
			resultUtil=new ResultUtil(0, "修改成功！", c1);
		}else {
			resultUtil=new ResultUtil(-1, "修改失败！", null);
		}
		return resultUtil;
	}

	@Transactional //开启事务
	@Override
	public ResultUtil manualAllocation(String sids) {
		List<Student> sList=new ArrayList<Student>();
		String[] sidArr=sids.split(",");
		for(int i=0;i<sidArr.length;i++) {
			//根据id获取学生信息
			Student s=studentRepository.findById(sidArr[i]).get();
			//如果该学生未分配咨询师
			if(s!=null&&s.getCounselor()==null) {
				//加入集合
				sList.add(s);
			}
		}
		//如果没有要分配的学生提示
		if(sList==null||sList.size()==0) {
			return new ResultUtil(-1, "没有要分配的学生！", null);
		}
		//获取已签到的咨询师
		List<Counselor> counselorList=this.getSignCounselor();
		
		//如果没有签到的咨询师
		if(counselorList==null||counselorList.size()==0) {
			return new ResultUtil(-1, "没有签到的咨询师！", null);
		}
		//随机分配咨询师
		List<Student> students=this.randomAllocation(sList, counselorList);
		//批量保存学生信息
		List<Student> slist1=studentRepository.saveAll(students);
		
		if(slist1!=null) {
			return new ResultUtil(0, "分配成功", slist1);
		}
		
		return new ResultUtil(-1, "分配失败", null);
	}
	/**
	 * 获取已签到的咨询师
	 * @return
	 */
	public List<Counselor> getSignCounselor(){
		List<Counselor> counselorList=new ArrayList<Counselor>();
		List<Counselor> counselors=counselorRepository.findAll();
		for (Counselor counselor : counselors) {
			//如果该咨询师已签到
			if("咨询师".equals(counselor.getRoleName())&&counselor.getSign_in_state()==1) {
				//加入集合
				counselorList.add(counselor);
			}
		}
		
		return counselorList;
	}

	/**
	 * 随机分配咨询师
	 * @param students 要分配的学生
	 * @param counselors 已经签到的咨询师
	 */
	public List<Student> randomAllocation(List<Student> students,List<Counselor> counselors) {
		Random random=new Random();
		//权重值
		int sumWeight=0;
		//创建按权重比例生成的咨询师集合
		List<Counselor> rCounselors=new ArrayList<Counselor>();
		
		//计算总权重值
		for (Counselor counselor : counselors) {
			sumWeight+=counselor.getWeight();
			//按权重生成等量的咨询师
			for (int i = 1; i <= counselor.getWeight(); i++) {
				rCounselors.add(counselor);
			}
		}
		
		//遍历学生
		for (Student s : students) {
			//如果学生未分配咨询师
			if(s.getCounselor()==null) {
				//打乱咨询师集合
				rCounselors=this.shuffle(rCounselors);
				//生成随机数
				int r=random.nextInt(rCounselors.size());
				//设置学生的咨询师信息为随机位置的咨询师
				s.setCounselor(rCounselors.get(r));
			}
		}
		//返回分配完成的学生集合
		return students;
	}
	
	/**
	 * 随机打乱集合顺序
	 * @param counselors
	 * @return
	 */
	private List<Counselor> shuffle(List<Counselor> counselors) {
		Random random=new Random();
		
		for (int i = 0; i < counselors.size(); i++) {
			//生成随机整数指定随机范围
			int r=random.nextInt(counselors.size());
			//将当前位置的咨询师赋值给中间值
			Counselor temp=counselors.get(i);
			//将当前位置的咨询师替换为随机位置的咨询师
			counselors.set(i, counselors.get(r));
			//将中间值赋值给随机位置
			counselors.set(r, temp);
		}
		//返回集合
		return counselors;
	}
	
	@Transactional //开启事务
	@Override
	public ResultUtil autoAllocation(String user_id) {
		String operation="";
		//根据id获取用户信息
		Users user=usersRepository.findById(user_id).get();
		//如果用户为空获取角色集合为空
		if(user==null||user.getRoles()==null) {
			return null;
		}
		
		Counselor c1=null;
		List<Counselor> clist1=null;
		//遍历角色集合
		for (Role role : user.getRoles()) {
			
			//咨询经理
			if("咨询经理".equals(role.getRole_name())) {
				//未开启自动分配的网络咨询师集合
				List<Counselor> netCounselors=new ArrayList<Counselor>();
				//未分配咨询师的学生集合
				List<Student> students=new ArrayList<Student>();
				//获取全部咨询师
				List<Counselor> counselorList=counselorRepository.findAll();
				//遍历获取未开启自动分配的网络咨询师
				for (Counselor counselor : counselorList) {
					if("网络咨询师".equals(counselor.getRoleName())&&"否".equals(counselor.getIs_allot())) {
						//开启自动分配
						counselor.setIs_allot("是");
						//加入网络咨询师集合
						netCounselors.add(counselor);
					}
				}
				
				
				if(netCounselors!=null&&netCounselors.size()>0) {
					operation="开启";
					//获取全部学生
					List<Student> sList=studentRepository.findAll();
					//遍历学生集合获取未分配学生
					for (Student student : sList) {
						if(student.getCounselor()==null) {
							//加入未分配咨询师的学生集合
							students.add(student);
						}
					}
					if(students!=null&&students.size()>0) {
						//获取已签到的咨询师
						List<Counselor> signCounselors=this.getSignCounselor();
						
						//随机分配咨询师
						this.randomAllocation(students, signCounselors);
					}
				}else {
					operation="关闭";
					//关闭全部网络咨询师的自动分配
					for (Counselor counselor : counselorList) {
						//设置关闭自动分配
						counselor.setIs_allot("否");
						//加入集合
						netCounselors.add(counselor);
					}
				}
				//批量修改网络咨询师开启自动分配
				clist1=counselorRepository.saveAll(netCounselors);
				break;
			}
			//网络咨询师
			if("网络咨询师".equals(role.getRole_name())) {
				//根据用户编号获取网络咨询师
				Counselor netCounselor=counselorRepository.getNetCounselorByUser_id(user_id);
				//判断网络咨询师是否开启自动分配
				if("否".equals(netCounselor.getIs_allot())) {
					operation="开启";
					//开启自动分配
					netCounselor.setIs_allot("是");
					//根据网络咨询师id获取未分配的学生
					List<Student> sList=studentRepository.getStudentByNetCounselor_id(netCounselor.getCounselor_id());
					//如果有未分配的学生
					if(sList!=null) {
						//获取已签到咨询师
						List<Counselor> counselors=this.getSignCounselor();
						if(counselors!=null) {
							//随机分配咨询师
							this.randomAllocation(sList, counselors);
						}
					}
				}else {
					operation="关闭";
					//关闭自动分配
					netCounselor.setIs_allot("否");
				}
				
				//保存网络咨询师
				c1=counselorRepository.saveAndFlush(netCounselor);
				break;
			}
		}
		
		if(c1!=null||clist1!=null) {
			return new ResultUtil(0, operation+"成功", c1);
		}
		return new ResultUtil(-1, operation+"失败", null);
	}

	@Override
	public ResultUtil getAutoAllocationStatus(String user_id) {
		ResultUtil resultUtil=null;
		//根据用户id获取用户信息
		Users user=usersRepository.findById(user_id).get();
		if(user!=null&&user.getRoles()!=null) {
			for (Role role : user.getRoles()) {
				if("咨询经理".equals(role.getRole_name())) {
					//获取全部咨询师
					List<Counselor> counselors=counselorRepository.findAll();
					//未开启自动分配的网络咨询师集合
					List<Counselor> netCounselors=new ArrayList<Counselor>();
					
					for (Counselor counselor : counselors) {
						//如果是网络咨询师并且未开启自动分配
						if("网络咨询师".equals(counselor.getRoleName())&&"否".equals(counselor.getIs_allot())) {
							//加入集合
							netCounselors.add(counselor);
						}
					}
					
					//如果有未开启自动分配的网络咨询师
					if(netCounselors!=null&&netCounselors.size()>0) {
						resultUtil=new ResultUtil(-1, "有网络咨询师未开启自动分配", null); 
					}else {
						resultUtil=new ResultUtil(0, "所有网络咨询师已开启自动分配", null); 
					}
					
					break;
				}
				//如果是网络咨询师
				if("网络咨询师".equals(role.getRole_name())) {
					//根据用户id获取网络咨询师
					Counselor netCounselor=counselorRepository.getNetCounselorByUser_id(user_id);
					if("是".equals(netCounselor.getIs_allot())) {
						resultUtil=new ResultUtil(0, "该网络咨询师已开启自动分配", null); 
					}else {
						resultUtil=new ResultUtil(-1, "该网络咨询师未开启自动分配", null); 
					}
					break;
				}
			}
		}else {
			resultUtil=new ResultUtil(-1, "未获取到用户角色信息！", null); 
		}
		return resultUtil;
	}

}
